#include "tuya_cloud_types.h"
#include "tal_api.h"
#include "tkl_output.h"
#include "tkl_gpio.h"

#include "gpio_key.h"

u32 	gpio_key_init_status = 0;

 struct key {
	u8  key_filter_value;
	u32 key_filter_timer;
	u8  key_last_value;
	u32 key_continue_timer;
	u8  key_code;
	u32  key_generate;
 };

struct key gpio_key[KEY_NUM];

void gpio_key_init(void);


void gpio_key_handler(struct key *keyp, u8 value)
{
	/*  value changed  */
	if (keyp->key_filter_value != value) {
		keyp->key_filter_value = value;
		keyp->key_filter_timer = sys_get_monotonic_250us();
		return ;
	}
	/*  if key value is same at 10ms, we consider it is stable  */
	if (sys_cal_pass_ms(keyp->key_filter_timer) < 10) {
		return;
	}
	keyp->key_filter_timer = sys_get_monotonic_250us();
	
	/*  key value is not changed  */
	if (keyp->key_last_value == keyp->key_filter_value) {
		/*  current key is not press down  */
		if (keyp->key_last_value == 0) {
			keyp->key_generate = KEY_NOKEY;
			keyp->key_continue_timer = sys_get_monotonic_250us();
			return;
		}
		/*  current key is press down, if press time exceed 500ms, it is long press key  */
		if (sys_cal_pass_ms(keyp->key_continue_timer) > 1000) {
			keyp->key_generate = keyp->key_code | KEY_CONTINUE;
		}
		return;
	}
	keyp->key_continue_timer = sys_get_monotonic_250us();
	/*  key value is changed  */
	if (keyp->key_last_value == 0) {
		/*  key is press  */
		keyp->key_generate = keyp->key_code | KEY_PRESS_DOWN;
	} else {
		/* key is release  */
		keyp->key_generate = keyp->key_code | KEY_PRESS_UP;
	}

	keyp->key_last_value = keyp->key_filter_value;
}
u32 gpio_key_get(void)
{
	u8 i;
	u32 key = KEY_NOKEY;
	
	for (i = 0; i < KEY_NUM; i++) {
		if (gpio_key[i].key_generate != KEY_NOKEY) {
			key = gpio_key[i].key_generate;
			gpio_key[i].key_generate = KEY_NOKEY;
			break;
		}
	}
	
	return key;
}


void gpio_key_loop()
{
	u8 key_value;
	u32 key;

	if (gpio_key_init_status == 0) {
		gpio_key_init();
	}
	
	key_value = gpio_key_value();
	gpio_key_handler(&gpio_key[0], key_value & (0x01));

//	key =  gpio_key_get();
//	if (key != KEY_NOKEY)
//		printf("key-> %04x %08x\r\n", key_value, key);
}

u8 gpio_key_value()
{
	TUYA_GPIO_LEVEL_E read_level;

	/* GPIO read */
	TUYA_CALL_ERR_LOG(tkl_gpio_read(TUYA_GPIO_NUM_7, &read_level));
	if (read_level == 1) {
		PR_DEBUG("GPIO read high level");
	} else {
		PR_DEBUG("GPIO read low level");
	}
}


void gpio_key_init(void)
{
	    /*GPIO input init*/
    TUYA_GPIO_BASE_CFG_T in_pin_cfg = {
        .mode = TUYA_GPIO_PULLUP,
        .direct = TUYA_GPIO_INPUT,
    };
    TUYA_CALL_ERR_LOG(tkl_gpio_init(TUYA_GPIO_NUM_7, &in_pin_cfg));
	
	gpio_key[0].key_code = KEY_LEFT;
	gpio_key_init_status = 1;
}
